using System.Collections.Generic;
using System.ComponentModel.Composition;
using Caliburn.Micro;
using MediaOwl.Common;
using MediaOwl.Common.Messages;
using MediaOwl.Common.ScreenManagement;
using MediaOwl.Netflix.Data;
using MediaOwl.Netflix.NetflixServiceReference;

namespace MediaOwl.Netflix.ViewModels
{
    [Export, PartCreationPolicy(CreationPolicy.NonShared)]
    public class MovieGenreSingleViewModel : Workitem<NetflixViewModel>
    {
        #region Fields
        private readonly INetflixDataRepository repository;
        private readonly IEventAggregator eventAggregator;

        #endregion

        #region Constructor
        [ImportingConstructor]
        public MovieGenreSingleViewModel(INetflixDataRepository repository, IEventAggregator eventAggregator)
        {
            this.repository = repository;
            this.eventAggregator = eventAggregator;
        }

        #endregion

        #region Properties & Backingfields

        private Genre currentGenre;
        public Genre CurrentGenre
        {
            get { return currentGenre; }
            set
            {
                currentGenre = value;
                NotifyOfPropertyChange(() => CurrentGenre);
                NotifyOfPropertyChange(() => LatestTitles);
                NotifyOfPropertyChange(() => BestTitles);
            }
        }

        private BindableCollection<Title> latestTitles;
        public BindableCollection<Title> LatestTitles
        {
            get { return latestTitles; }
            set
            {
                latestTitles = value;
                NotifyOfPropertyChange(() => LatestTitles);
            }
        }

        private BindableCollection<Title> bestTitles;
        public BindableCollection<Title> BestTitles
        {
            get { return bestTitles; }
            set
            {
                bestTitles = value;
                NotifyOfPropertyChange(() => BestTitles);
            }
        }

        #endregion

        #region Methods

        public void WithGenre(Genre genre)
        {
            if (genre == null)
                return;
            DisplayName = genre.Name;
            Run.Coroutine(FetchData(genre));
        }

        private IEnumerable<IResult> FetchData(Genre withgenre)
        {
            yield return Show.Busy(this);

            CurrentGenre = withgenre;

            if (CurrentGenre != null)
            {
                yield return repository.GetBestTitlesByGenre(withgenre.Name,
                                                             (titles, count) => BestTitles = new BindableCollection<Title>(titles),
                                                             x => eventAggregator.Publish(new ErrorMessage(x)), 1, 30);

                yield return repository.GetLatestTitlesByGenre(withgenre.Name,
                                                               (titles, count) => LatestTitles = new BindableCollection<Title>(titles),
                                                               x => eventAggregator.Publish(new ErrorMessage(x)), 1, 30);
            }

            yield return Show.NotBusy(this);
        }

        public IEnumerable<IResult> OpenTitle(object selectedItem)
        {
            if (selectedItem is Title)
            {
                yield return Show.Child<MovieTitleSingleViewModel>(Helper.GetScreenId(selectedItem))
                    .In(Parent)
                    .Configured(x => x.WithTitle((Title) selectedItem));
            }
        }

        public IEnumerable<IResult> OpenPerson(object selectedItem)
        {
            if (selectedItem is Person)
            {
                yield return Show.Child<MoviePersonSingleViewModel>(Helper.GetScreenId(selectedItem))
                    .In(Parent)
                    .Configured(x => x.WithPerson((Person)selectedItem));
            }
        }

        #endregion
    }
}